package edu.pw.p2pclient.activities;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.location.Location;
import android.location.LocationManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import edu.pw.p2pclient.R;
import edu.pw.p2pclient.data.Node;
import edu.pw.p2pclient.data.Resource;
import edu.pw.p2pclient.data.TreeNode;
import edu.pw.p2pclient.logic.AvailableManager;
import edu.pw.p2pclient.logic.SharedManager;
import edu.pw.p2pclient.networking.CommunicationService;
import edu.pw.p2pclient.networking.webservice.Response;
import edu.pw.p2pclient.networking.webservice.WebServiceTask;
import edu.pw.p2pclient.utils.ApplicationContext;

@SuppressWarnings("deprecation")
public class SettingsActivity extends PreferenceActivity implements
		OnSharedPreferenceChangeListener, OnPreferenceClickListener {

	// public final static String LOCALISATION_PREF = "localisation_manner";
	public final static String PUBLISH_NETWORK_PREF = "publish_network";
	public final static String DELETE_NETWORK_PREF = "delete_network";
	public final static String UNKNOWN_SOURCES_PREF = "accept_unknown_sources";
	public final static String BLACKLIST_PREF = "modify_blacklist";
	public final static String WHITELIST_PREF = "modify_whitelist";
	public final static String SHARING_PREF = "sharing";
	public final static String AUTOSTART_PREF = "autostart";
	public final static String WEB_TYPE_PREF = "interfaces";

	private final static String TAG = "SettingsActivity";

	private LocationManager mLocationManager;
	private MyWebLocationListener mLocationListener;

	// ListPreference mLocalisationPref;
	Preference mPublishNetworkPref;
	Preference mDeleteNetworkPref;
	CheckBoxPreference mUnknownSourcesPref;
	Preference mBlacklist;
	Preference mWhitelist;
	CheckBoxPreference mSharingPref;
	CheckBoxPreference mAutostartPref;
	ListPreference mWebTypePref;

	@Override
	protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		ApplicationContext.init(getApplicationContext());
		addPreferencesFromResource(R.xml.prefs);
		setContentView(R.layout.activity_settings);

		// mLocalisationPref = (ListPreference)
		// findPreference(LOCALISATION_PREF);
		mPublishNetworkPref = (Preference) findPreference(PUBLISH_NETWORK_PREF);
		mDeleteNetworkPref = (Preference) findPreference(DELETE_NETWORK_PREF);
		mUnknownSourcesPref = (CheckBoxPreference) findPreference(UNKNOWN_SOURCES_PREF);
		mBlacklist = (Preference) findPreference(BLACKLIST_PREF);
		mWhitelist = (Preference) findPreference(WHITELIST_PREF);
		mSharingPref = (CheckBoxPreference) findPreference(SHARING_PREF);
		mAutostartPref = (CheckBoxPreference) findPreference(AUTOSTART_PREF);
		mWebTypePref = (ListPreference) findPreference(WEB_TYPE_PREF);

		mPublishNetworkPref.setOnPreferenceClickListener(this);
		mDeleteNetworkPref.setOnPreferenceClickListener(this);
		mBlacklist.setOnPreferenceClickListener(this);
		mWhitelist.setOnPreferenceClickListener(this);
		SharedPreferences p = PreferenceManager
				.getDefaultSharedPreferences(getApplicationContext());

		// mLocalisationPref.setSummary(p.getString(LOCALISATION_PREF, ""));
		mWebTypePref.setSummary(p.getString(WEB_TYPE_PREF, ""));
	}

	@Override
	protected void onPause() {

		getPreferenceScreen().getSharedPreferences()
				.unregisterOnSharedPreferenceChangeListener(this);
		super.onPause();
	}

	@Override
	protected void onResume() {

		getPreferenceScreen().getSharedPreferences()
				.registerOnSharedPreferenceChangeListener(this);
		super.onResume();
	}

	@Override
	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
			String key) {

		// if (key.equals(LOCALISATION_PREF))
		// mLocalisationPref.setSummary(sharedPreferences.getString(
		// LOCALISATION_PREF, ""));
		// else
		if (key.equals(UNKNOWN_SOURCES_PREF)) {

		} else if (key.equals(SHARING_PREF)) {
			if (mSharingPref.isChecked())
				startService(new Intent(getApplicationContext(),
						CommunicationService.class));
			else
				stopService(new Intent(getApplicationContext(),
						CommunicationService.class));
		} else if (key.equals(WEB_TYPE_PREF))
			mWebTypePref.setSummary(sharedPreferences.getString(WEB_TYPE_PREF,
					""));
	}

	@Override
	public boolean onPreferenceClick(Preference preference) {
		if (preference.getKey().equals(BLACKLIST_PREF)) {
			return true;
		} else if (preference.getKey().equals(WHITELIST_PREF)) {
			return true;
		} else if (preference.getKey().equals(PUBLISH_NETWORK_PREF)
				|| preference.getKey().equals(DELETE_NETWORK_PREF)) {
			String wifiName = null;
			try {
				WifiManager wifiManager = (WifiManager) getApplicationContext()
						.getSystemService(Context.WIFI_SERVICE);
				WifiInfo wifiInfo = wifiManager.getConnectionInfo();

				wifiName = wifiInfo.getSSID();
			} catch (Exception a) {
			}
			if (wifiName == null) {
				Log.i(TAG, "No wifi!");
				wifiName = "";
			} else if (wifiName.startsWith("\"") && wifiName.endsWith("\"")) {
				wifiName = wifiName.substring(1, wifiName.length() - 1);
			}

			LayoutInflater inflater = getLayoutInflater();
			View view = inflater.inflate(R.layout.publish_network_dialog, null);
			final EditText networkName = (EditText) view
					.findViewById(R.id.networkName);
			final EditText networkPassword = (EditText) view
					.findViewById(R.id.networkPassword);
			final ToggleButton btToggleButton = (ToggleButton) view
					.findViewById(R.id.btToggleButton);
			final ToggleButton wifiToggleButton = (ToggleButton) view
					.findViewById(R.id.wifiToggleButton);

			AlertDialog.Builder builder = new Builder(SettingsActivity.this);
			builder.setView(view);

			if (preference.getKey().equals(PUBLISH_NETWORK_PREF)) {
				mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
				mLocationListener = new MyWebLocationListener(mLocationManager);
				if (mLocationManager
						.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
					mLocationManager.requestLocationUpdates(
							LocationManager.GPS_PROVIDER, 5000, 10,
							mLocationListener);
					Log.i(TAG, "GPS Location enabled");
				}
				if (mLocationManager
						.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
					mLocationManager.requestLocationUpdates(
							LocationManager.NETWORK_PROVIDER, 5000, 10,
							mLocationListener);
					Log.i(TAG, "Network Location enabled");
				}
				if (wifiName.equals("")) {
					networkName.setEnabled(true);
					networkName.setText("");
					networkPassword.setEnabled(false);
					btToggleButton.setChecked(true);
					wifiToggleButton.setChecked(false);
				} else {
					networkName.setEnabled(false);
					networkName.setText(wifiName);
					networkPassword.setEnabled(true);
					btToggleButton.setChecked(false);
					wifiToggleButton.setChecked(true);
				}
				builder.setTitle(R.string.publish_network);
				builder.setPositiveButton(R.string.publish_network,
						new DialogInterface.OnClickListener() {

							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								mPublishNetworkPref.setEnabled(false);
								GsonBuilder gsonBuilder = new GsonBuilder();
								gsonBuilder.registerTypeAdapter(Node.class,
										Node.serializer);
								gsonBuilder.registerTypeAdapter(TreeNode.class,
										Node.serializer);
								gsonBuilder.registerTypeAdapter(Resource.class,
										Node.serializer);
								Gson gson = gsonBuilder.create();
								List<NameValuePair> list = new ArrayList<NameValuePair>(
										7);

								list.add(new BasicNameValuePair(
										"regId",
										RequestActivity
												.getRegistrationId(getApplicationContext())));
								list.add(new BasicNameValuePair("networkName",
										networkName.getText().toString()));
								list.add(new BasicNameValuePair(
										"networkPassword", networkPassword
												.getText().toString()));
								list.add(new BasicNameValuePair("bluetooth",
										btToggleButton.isEnabled() ? "1" : "0"));
								LinkedHashSet<Node> tmp = new LinkedHashSet<Node>(
										AvailableManager.getInstance()
												.getResources());
								tmp.addAll(SharedManager.getInstance()
										.getBtWifiShared());
								list.add(new BasicNameValuePair("resources",
										gson.toJson(tmp)));
								mLocationListener.setList(list);

								Toast.makeText(
										getApplicationContext(),
										R.string.will_be_published_after_location,
										Toast.LENGTH_LONG).show();
							}
						});
			} else {
				networkName.setEnabled(true);
				networkName.setText(wifiName);
				networkPassword.setVisibility(View.GONE);
				builder.setTitle(R.string.delete_network);
				builder.setPositiveButton(R.string.delete_network,
						new DialogInterface.OnClickListener() {

							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								List<NameValuePair> list = new ArrayList<NameValuePair>(
										4);

								list.add(new BasicNameValuePair(
										"regId",
										RequestActivity
												.getRegistrationId(getApplicationContext())));
								list.add(new BasicNameValuePair("networkName",
										networkName.getText().toString()));
								list.add(new BasicNameValuePair(
										"networkPassword", networkPassword
												.getText().toString()));
								list.add(new BasicNameValuePair("bluetooth",
										btToggleButton.isEnabled() ? "1" : "0"));

								new WebServiceTask("deleteNetwork", list) {
									@Override
									protected void onPreExecute() {
										mDeleteNetworkPref.setEnabled(false);
									}

									@Override
									protected void onPostExecute(Response result) {
										mDeleteNetworkPref.setEnabled(true);
										if (result == null
												|| !result.isSuccessfull())
											Toast.makeText(
													getApplicationContext(),
													R.string.something_went_wrong,
													Toast.LENGTH_SHORT).show();
										else
											mPublishNetworkPref
													.setEnabled(true);
									}
								}.execute();
							}
						});
			}

			builder.setNegativeButton(R.string.cancel,
					new DialogInterface.OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
						}
					});
			builder.show();
			return true;
		}
		return false;
	}

	private class MyWebLocationListener extends MyLocationListener {

		private List<NameValuePair> mList = null;

		public MyWebLocationListener(LocationManager manager) {
			super(manager);
		}

		public void setList(List<NameValuePair> list) {
			mList = list;
			tryToPublish();
		}

		@Override
		public synchronized void onLocationChanged(Location location) {
			super.onLocationChanged(location);
			tryToPublish();
		}

		private void tryToPublish() {
			if (mCurrentLocation != null && mList != null) {
				List<NameValuePair> tmp = mList;
				mList = null;
				tmp.add(new BasicNameValuePair("latitude", String
						.valueOf(mCurrentLocation.getLatitude())));
				tmp.add(new BasicNameValuePair("longitude", String
						.valueOf(mCurrentLocation.getLongitude())));

				new WebServiceTask("publishNetwork", tmp) {

					protected void onPostExecute(Response result) {
						if (result == null || !result.isSuccessfull()) {
							mPublishNetworkPref.setEnabled(true);
							Toast.makeText(getApplicationContext(),
									R.string.something_went_wrong,
									Toast.LENGTH_SHORT).show();
						}
						mLocationManager.removeUpdates(mLocationListener);
					};

				}.execute();
			}
		}
	};
}
